home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / examples / misc / spring.pro < prev    next >
Text File  |  1997-07-08  |  20KB  |  583 lines

  1. ; $Id: spring.pro,v 1.10 1997/01/15 04:21:02 ali Exp $
  2. ;
  3. ; Copyright (c) 1991-1997, Research Systems, Inc.  All rights reserved.
  4. ;       Unauthorized reproduction prohibited.
  5. ;+
  6. ; NAME: Spring
  7. ;
  8. ; PURPOSE: This example demonstrates the fundamental principles of statistical
  9. ;          time-series analysis.
  10. ;
  11. ; MAJOR TOPICS: Surface Drawing and Widgets.
  12. ;
  13. ; CALLING SEQUENCE: Spring
  14. ;
  15. ; PROCEDURE: Spring computes ...
  16. ;
  17. ; MAJOR FUNCTIONS and PROCEDURES:
  18. ;
  19. ; COMMON BLOCKS and STRUCTURES:
  20. ;       springCommon : This common block contains...
  21. ;
  22. ; MODIFICATION HISTORY:  Written by:  DMS, RSI, March 1991
  23. ;                        Modified by: WSO, RSI, January 1995
  24. ;-
  25.  
  26.     ;
  27.     ; Return the correct color depending on the color depth used.  If !D.N_COLORS
  28.     ; is greater than 256, then the output device is in true color mode.  If that's
  29.     ; the case, we want to use the same index from the red, green and blue color
  30.     ; tables to get the desired color.  If it's not true color than just return 
  31.     ; the color table index.
  32.     ;
  33. FUNCTION GetColor, colorIndex
  34.  
  35.    IF (!D.N_COLORS GT 256) THEN $
  36.       RETURN, (colorIndex * 256L + colorIndex) * 256L + colorIndex $
  37.    ELSE $
  38.       RETURN, colorIndex
  39. END
  40.  
  41.  
  42. ;----------------------------------------
  43.    ; Draw square in mark window at cell (x,y)
  44. PRO MarkSquare, x, y, color
  45.  
  46.      ; Grid is one fifth the size of the edit area
  47.    x = x * 5
  48.    y = y * 5
  49.  
  50.      ; Build square to mark spring location in edit area
  51.    p0 = [x+1, y]
  52.    p1 = [x+5, y+4]
  53.  
  54.    POLYFILL, [p0[0], p1[0], p1[0], p0[0]], [p0[1], p0[1], p1[1], p1[1]], $
  55.      COLOR=GetColor(color), /DEVICE
  56. END
  57.  
  58.  
  59. ;----------------------------------------
  60. PRO DrawGrid
  61.  
  62. COMMON springCommon, cNumberOfFrames, cImageSize, cSpringStrength, $
  63.                    cMaxSpringStrength, cGridSize, cMethodNames, $
  64.                    cXAxisRotation, cZAxisRotation, cAxSlider, cAzSlider, $
  65.                    cGrid, cViewDrawArea, cSpringDisplacement, cEditDrawArea, $
  66.                    cEditDrawAreaID, cRenderMethod, cSpringWindow
  67.  
  68.    WSET, cEditDrawArea
  69.    ERASE
  70.  
  71.    FOR iy = 0, 160, 5 DO $
  72.       PLOTS,[0, 160], [iy, iy], COLOR=GetColor(180), /DEVICE   ;Draw the grid
  73.    FOR ix=  0, 160, 5 DO $
  74.       PLOTS,[ix, ix], [0, 160], COLOR=GetColor(180), /DEVICE
  75.  
  76.    FOR ix = 0, cGridSize-1 DO $
  77.       FOR iy =  0, cGridSize-1 DO BEGIN
  78.          IF (cGrid[ix, iy] LT 0.) OR (cGrid[ix, iy] GT 0.) THEN $
  79.             MarkSquare, ix[0], iy[0], 0
  80.       ENDFOR
  81. END
  82.  
  83.  
  84. PRO DrawShadedSquares, theScaledGrid, theDisplacementGrid, $
  85.            minDisplacement, maxDisplacement
  86.  
  87. COMMON springCommon
  88.       
  89.    SURFR, AX=cXAxisRotation, AZ=cZAxisRotation      ;Set the scaling
  90.  
  91.    !X.S = [ 0, 1. / cGridSize ]
  92.    !Y.S = !X.S
  93.    !Z.S = [-minDisplacement, maxDisplacement] / $
  94.                   (maxDisplacement - minDisplacement)
  95.    ERASE
  96.  
  97.    del = 0.04         ;Fudge factor to cover surface
  98.  
  99.    px = [ -del, 1.+del, 1.+del, -del]   ;Basic polygon
  100.    py = [ -del, -del, 1.+del, 1.+del]
  101.  
  102.    FOR iy = cGridSize-1, 0, -1 DO $
  103.       FOR ix = 0, cGridSize-1 DO $ ;Draw squares
  104.          POLYFILL, px+ix, py+iy, $
  105.            REPLICATE(theDisplacementGrid[ix, iy], 4), /T3D, $
  106.              COLOR=GetColor(theScaledGrid[ix,iy])
  107. END
  108.  
  109.  
  110. ;----------------------------------------
  111. ; Draws spring frame
  112. ;
  113. PRO DrawSurface, imageSize, DISPLACEMENTGRID=displacementGrid, $
  114.           VELOCITYGRID=velocityGrid, $
  115.           MAXDISPLACEMENT=maxDisplacement, MINDISPLACEMENT=minDisplacement, $
  116.           MAXVELOCITY=maxVelocity, MINVELOCITY=minVelocity
  117.  
  118. COMMON springCommon
  119.       
  120.    rebinSize = (imageSize / cGridSize) * cGridSize
  121.  
  122.    topColor = !D.TABLE_SIZE-1
  123.       
  124.    CASE cRenderMethod OF         ;Which rendering?
  125.       
  126.            ; Surface
  127.       0: SURFACE, displacementGrid, $
  128.            ZRANGE=[minDisplacement, maxDisplacement], $
  129.            AX=cXAxisRotation, AZ=cZAxisRotation
  130.          
  131.            ; Shaded surface (light source)
  132.       1: SHADE_SURF, displacementGrid, $
  133.            ZRANGE=[minDisplacement, maxDisplacement], $
  134.            AX=cXAxisRotation, AZ=cZAxisRotation
  135.  
  136.            ; Altitude shaded surface
  137.       2: SHADE_SURF, displacementGrid, SHADES=BYTSCL(displacementGrid, $
  138.            TOP=topColor, MIN=minDisplacement, MAX=maxDisplacement),$
  139.            ZRANGE=[minDisplacement, maxDisplacement], $
  140.            AX=cXAxisRotation, AZ=cZAxisRotation
  141.  
  142.            ; Velocity shaded surface
  143.       3: SHADE_SURF, displacementGrid, SHADES=BYTSCL(velocityGrid, $
  144.            TOP=topColor, MAX=maxVelocity, MIN=minVelocity),$
  145.            ZRANGE=[minDisplacement, maxDisplacement], $
  146.            AX=cXAxisRotation, AZ=cZAxisRotation
  147.  
  148.            ; Image of displacement
  149.       4: TV, REBIN(BYTSCL(displacementGrid, MAX=maxDisplacement, $
  150.                      MIN = minDisplacement), rebinSize, rebinSize)
  151.          
  152.            ; Image of velocity
  153.       5: TV, REBIN(BYTSCL(velocityGrid, MAX=maxVelocity, $
  154.                      MIN=minVelocity), rebinSize, rebinSize)
  155.          
  156.            ; Contour
  157.       6: CONTOUR, displacementGrid, LEVELS=FINDGEN(16.)/8.-1., XSTYLE=5, $
  158.            YSTYLE=5, C_COLORS=topColor * 0.5 * FINDGEN(16)/8.
  159.          
  160.            ; Squares by displacement
  161.       7: BEGIN
  162.          theScaledGrid = BYTSCL(displacementGrid, MIN=minDisplacement, $
  163.                MAX=maxDisplacement, TOP=topColor)   ;shades
  164.  
  165.          DrawShadedSquares, theScaledGrid, displacementGrid, $
  166.            minDisplacement, maxDisplacement
  167.  
  168.          ENDCASE         ; Squares by displacement
  169.       
  170.            ; Squares by velocity
  171.       8: BEGIN   
  172.          theScaledGrid = BYTSCL(ABS(velocityGrid), MIN=0, MAX=maxVelocity, $
  173.                            TOP=topColor)
  174.          DrawShadedSquares, theScaledGrid, displacementGrid, $
  175.            minDisplacement, maxDisplacement
  176.          ENDCASE         ; Squares by velocity
  177.  
  178.       ENDCASE
  179.    
  180. END
  181.  
  182.  
  183. ;----------------------------------------
  184. ; Does the calculations & drawing for spring animation
  185. ;
  186. PRO DrawSpring, GROUP = group
  187.  
  188. COMMON springCommon
  189.  
  190.      ; Deactivate all window controls
  191.    WIDGET_CONTROL, cSpringWindow, SENSITIVE = 0
  192.       
  193.      ; Starting displacements, allow for border reflection
  194.    displacementGrid = FLTARR(cGridSize+2, cGridSize+2)
  195.      ; Insert starting displacements
  196.    displacementGrid[1,1] = cGrid
  197.      ; Starting velocity
  198.    velocityGrid = FLTARR(cGridSize+2, cGridSize+2)
  199.  
  200.      ; Set up animation
  201.    XINTERANIMATE, SET=[cImageSize, cImageSize, cNumberOfFrames], $
  202.             TITLE = cMethodNames[cRenderMethod], /SHOWLOAD, /CYCLE, /TRACK
  203.  
  204.    currentWindow = !D.WINDOW
  205.    ERASE
  206.  
  207.      ; Do all at once, displacement
  208.    displacementFrames = FLTARR(cGridSize, cGridSize, cNumberOfFrames, /NOZERO)
  209.    velocityFrames = displacementFrames            ;Velocity
  210.    
  211.      ; Make kernel for convolution
  212.    sq21 = 1./SQRT(2)
  213.    kernel = cSpringStrength * [[ sq21, 1, sq21], [1, 0, 1], [sq21, 1, sq21]]
  214.    kernel[1,1] = -TOTAL(kernel)
  215.  
  216.    FOR iteration = 0, cNumberOfFrames-1 DO BEGIN   ;Each iteration
  217.         ; Calculate new velocity
  218.       velocityGrid = velocityGrid + CONVOL(displacementGrid, kernel)
  219.         ; Calculate new displacement
  220.       displacementGrid = displacementGrid + velocityGrid
  221.         ; Save for scaling
  222.       velocityFrames[0, 0, iteration] = velocityGrid[1:cGridSize, 1:cGridSize]
  223.  
  224.       displacementFrames[0, 0, iteration] = $
  225.         displacementGrid[1:cGridSize, 1:cGridSize]
  226.    ENDFOR
  227.    
  228.      ; Get scaling
  229.    maxVelocity = MAX(velocityFrames, MIN=minVelocity)
  230.    maxDisplacement = MAX(displacementFrames, MIN=minDisplacement)
  231.  
  232.    FOR iteration = 0, cNumberOfFrames-1 DO BEGIN  ; Each frame
  233.  
  234.       displacementGrid = displacementFrames[*,*,iteration]
  235.       velocityGrid = velocityFrames[*,*,iteration]
  236.    
  237.       DrawSurface, cImageSize, DISPLACEMENTGRID=displacementGrid, $
  238.         VELOCITYGRID=velocityGrid, $
  239.         MAXDISPLACEMENT=maxDisplacement, MINDISPLACEMENT=minDisplacement, $
  240.         MAXVELOCITY=maxVelocity, MINVELOCITY=minVelocity
  241.           
  242.       XINTERANIMATE, FRAME=iteration, WINDOW=currentWindow
  243.    ENDFOR
  244.  
  245.      ; Active the window controls again
  246.    WIDGET_CONTROL, cSpringWindow, SENSITIVE = 1
  247.    XINTERANIMATE, GROUP = group, 20
  248.  
  249. END
  250.  
  251.  
  252.  
  253. ;----------------------------------------
  254. PRO SpringEvent, event
  255.  
  256. COMMON springCommon
  257.  
  258.      ; Find the user value of the widget where the event occured
  259.    WIDGET_CONTROL, event.id, GET_UVALUE = widgetName     
  260.  
  261.    CASE widgetName OF
  262.      "METHOD_GROUP": BEGIN
  263.  
  264.          cRenderMethod = event.index
  265.  
  266.            ; If render method is "Displacement Image" or "Velocity Image" or
  267.            ; "Contour Plot" then disable x and z axis rotation since they're
  268.            ; only 2 dimensional
  269.          IF (cRenderMethod GE 4 AND cRenderMethod LE 6) THEN BEGIN
  270.             WIDGET_CONTROL, cAxSlider, SENSITIVE=0
  271.             WIDGET_CONTROL, cAzSlider, SENSITIVE=0
  272.          ENDIF ELSE BEGIN
  273.             WIDGET_CONTROL, cAxSlider, SENSITIVE=1
  274.             WIDGET_CONTROL, cAzSlider, SENSITIVE=1
  275.          ENDELSE
  276.  
  277.          swin = !D.WINDOW
  278.          WSET, cViewDrawArea
  279.  
  280.          maxDisplacement = MAX(cGrid, MIN=minDisplacement)
  281.  
  282.          DrawSurface, 192, DISPLACEMENTGRID=cGrid, VELOCITYGRID=cGrid, $
  283.            MAXDISPLACEMENT=maxDisplacement, MINDISPLACEMENT=minDisplacement, $
  284.            MAXVELOCITY=maxDisplacement, MINVELOCITY=minDisplacement
  285.          WSET, swin
  286.       ENDCASE
  287.          
  288.      "KSPRING_SLIDER": cSpringStrength = event.value * cMaxSpringStrength / 100
  289.      
  290.      "NUM_FRAMES_SLIDER": cNumberOfFrames = event.value
  291.  
  292.      "MARK_DRAW_AREA": BEGIN
  293.  
  294.          IF event.press EQ 0 THEN $
  295.             RETURN   ; Ignore release
  296.  
  297.          swin = !D.WINDOW
  298.          WSET, cEditDrawArea
  299.  
  300.          p = [ event.x/5, event.y/5 ] 
  301.          p[0] = FIX(p[0]) > 0 < (cGridSize-1)
  302.          p[1] = FIX(p[1]) > 0 < (cGridSize-1)
  303.  
  304.          IF (cGrid[p[0], p[1]] EQ 0) THEN BEGIN ; Mark???
  305.             cGrid[p[0], p[1]] = cSpringDisplacement/100.
  306.             MarkSquare, p[0], p[1], 0 ; Draw in black mark
  307.          ENDIF ELSE BEGIN
  308.             cGrid[p[0], p[1]] = 0.
  309.             MarkSquare, p[0], p[1], !D.TABLE_SIZE-1  ; Erase old - with white mark
  310.          ENDELSE
  311.  
  312.          WSET, cViewDrawArea
  313.  
  314.          maxDisplacement = MAX(cGrid, MIN=minDisplacement)
  315.  
  316.          DrawSurface, 192, DISPLACEMENTGRID=cGrid, VELOCITYGRID=cGrid, $
  317.            MAXDISPLACEMENT=maxDisplacement, MINDISPLACEMENT=minDisplacement, $
  318.            MAXVELOCITY=maxDisplacement, MINVELOCITY=minDisplacement
  319.  
  320.          WSET, swin
  321.  
  322.       ENDCASE
  323.      
  324.      "HTSLIDER" :  cSpringDisplacement = event.value
  325.  
  326.      "AX_SLIDER" : BEGIN
  327.  
  328.          cXAxisRotation = event.value
  329.  
  330.      swin = !D.WINDOW
  331.          WSET, cViewDrawArea
  332.  
  333.          maxDisplacement = MAX(cGrid, MIN=minDisplacement)
  334.  
  335.          DrawSurface, 192, DISPLACEMENTGRID=cGrid, VELOCITYGRID=cGrid, $
  336.            MAXDISPLACEMENT=maxDisplacement, MINDISPLACEMENT=minDisplacement, $
  337.            MAXVELOCITY=maxDisplacement, MINVELOCITY=minDisplacement
  338.          WSET, swin
  339.  
  340.       ENDCASE
  341.          
  342.      "AZ_SLIDER" : BEGIN
  343.  
  344.          cZAxisRotation = event.value
  345.  
  346.      swin = !D.WINDOW
  347.          WSET, cViewDrawArea
  348.  
  349.          maxDisplacement = MAX(cGrid, MIN=minDisplacement)
  350.  
  351.          DrawSurface, 192, DISPLACEMENTGRID=cGrid, VELOCITYGRID=cGrid, $
  352.            MAXDISPLACEMENT=maxDisplacement, MINDISPLACEMENT=minDisplacement, $
  353.            MAXVELOCITY=maxDisplacement, MINVELOCITY=minDisplacement
  354.      WSET, swin
  355.       ENDCASE
  356.  
  357.      "ANIMATE" : $
  358.          IF XREGISTERED("XInterAnimate") EQ 0 THEN $
  359.             DrawSpring, GROUP=event.top
  360.      
  361.      "INFO" : BEGIN
  362.  
  363.          infoText = [ $
  364.           "The Spring example is a dynamic simulation of a "+ $
  365.           "rectangular grid of weights connected by springs.  The "+ $
  366.           "results may be visualized by a number of methods, "+ $
  367.           "illustrating some of the many ways of displaying data with IDL. ", "", $
  368.           "Pressing the Animate button starts the simulation from an "+ $
  369.           "initial starting grid.  The initial Z position of the "+ $
  370.           'weights may be edited. To edit, set the "Spring Displacement"'+ $
  371.           "to the new Z value (range: -100 to 100), and click on the cell's position "+ $
  372.           "in the left hand grid.  The X and "+ $
  373.           "Y position of the weights is fixed.  The strength of "+ $
  374.           "the springs may be varied, as well as a number of "+ $
  375.           "viewing and simulation parameters. ", "", $
  376.           "WARNING: this example can easily exhaust the memory / swap "+ $
  377.           "space resources of small or improperly configured machines. ", "", $
  378.           "**** CONTROLS **** ", "", $
  379.           "Animate button: starts the simulation from the starting "+ $
  380.           "grid.  Each frame is rendered and the XINTERANIMATE "+ $
  381.           "procedure is called to animate the results. ", "", $
  382.           "Info... button:  Displays this text. ", "", $
  383.           "Rendering Methods: select a method, by clicking in the drop list. ", "", $
  384.           "Spring Strength slider: Sets the spring coefficient.  A "+ $
  385.           "higher setting makes the springs stronger in relation "+ $
  386.           "to the weights.  Higher settings result in more "+ $
  387.           "movement; lower settings result in smoother simulations.  ", "", $
  388.           "X axis rotation slider: Controls the rotation about the "+ $
  389.           "X axis for the 3D displays. ", "", $
  390.           "Z axis rotation slider: Controls the rotation about the "+ $
  391.           "Z axis for 3D displays. ", "", $
  392.           "Number of frames: The number of animation frames in the "+ $
  393.           "animation.  The amount of display memory is "+ $
  394.           "proportional to this number.  WARNING: this demo can "+ $
  395.           "easily exhaust the memory / swap space resources of small machines. "]
  396.  
  397.          ShowInfo, TITLE="Spring Example Information", GROUP=event.top, WIDTH=80,$
  398.            HEIGHT=24, INFOTEXT=infoText
  399.          ENDCASE
  400.          
  401.       ELSE: $ ; When an event occurs in a widget that has no user value in this
  402.               ; case statement, an error message is shown
  403.          MESSAGE, "Event User Value Not Found"      
  404.  
  405.    ENDCASE
  406.    
  407. END ;============= end of Spring event handling routine task =============
  408.  
  409.  
  410. PRO CleanUpSpring, wSpringWindow
  411.  
  412.      ; Get the color table saved in the window's user value
  413.    WIDGET_CONTROL, wSpringWindow, GET_UVALUE=previousState
  414.    
  415.      ; Restore the previous color table.
  416.    TVLCT, previousState.colorTable
  417.  
  418.      ; Restore the previous background color.
  419.    !P.BACKGROUND = previousState.backgroundColor
  420.  
  421.      ; Restore the previous pen color.
  422.    !P.COLOR = previousState.penColor
  423. END
  424.  
  425.  
  426. ;----------------------------------------
  427. PRO Spring, GROUP = group
  428.  
  429. COMMON springCommon
  430.  
  431.    IF XREGISTERED("Spring") THEN $
  432.       RETURN      ;only one instance
  433.  
  434.    IF XREGISTERED("XInterAnimate") THEN BEGIN
  435.       tmp = DIALOG_MESSAGE(/ERROR, ['Can''t run Surface Drawing Demo.', ' ', $
  436.                      'Only one animation can be active at a time.' ])
  437.       RETURN
  438.    ENDIF
  439.  
  440.    swin = !D.WINDOW
  441.  
  442.      ; Get the current color vectors to restore when this application is exited.
  443.    TVLCT, savedR, savedG, savedB, /GET
  444.    
  445.      ; Save items to be restored on exit in a structure
  446.    previousState = {colorTable: [[savedR],[savedG],[savedB]], $
  447.                     backgroundColor: !P.BACKGROUND, $
  448.                     penColor: !P.COLOR}
  449.    
  450.      ; Remove axis from all plots
  451.    !X.STYLE = 4
  452.    !Y.STYLE = 4
  453.    !Z.STYLE = 4
  454.    !X.MARGIN = 0
  455.    !Y.MARGIN = 0
  456.  
  457.      ; Set up defaults and constants:
  458.    IF N_ELEMENTS(cNumberOfFrames) LE 0 THEN BEGIN
  459.       cNumberOfFrames = 16     ; Initial values
  460.       cImageSize = 256         ; Size of spring animation draw widget
  461.       cMaxSpringStrength = 0.2 ; Largest possible spring const
  462.       cSpringStrength = 0.05   ; Initialize spring const
  463.       cGridSize = 32           ; Initialize grid size
  464.       cEditDrawAreaID = 0
  465.  
  466.       cGrid = FLTARR(cGridSize, cGridSize)  ; Starting grid
  467.       cGrid[cGridSize/3, cGridSize/3] = 1.
  468.    
  469.       cSpringDisplacement = 100
  470.       
  471.       cMethodNames = [ $
  472.          "Mesh Surface",$
  473.          "Light Source Shaded Surface", $
  474.          "Displacement Shaded Surface", $
  475.          "Velocity Shaded Surface",$
  476.          "Displacement Image",$
  477.          "Velocity Image",$
  478.          "Contour Plot", $
  479.          "Displacement Shaded Squares",$
  480.          "Velocity Shaded Squares"]
  481.  
  482.       cXAxisRotation = 15         ;X axis rotation
  483.       cZAxisRotation = 20         ;Z axis rotation
  484.    ENDIF 
  485.  
  486.      ; Initial rendering method is here to longest name to force
  487.      ; menu to the largest size
  488.    cRenderMethod = 1 
  489.  
  490.    LOADCT, 0, /SILENT
  491.  
  492.      ; Initialize the background to white
  493.    !P.BACKGROUND = GetColor(!D.TABLE_SIZE-1)
  494.      ; Initialize the pen color to black
  495.    !P.COLOR = GetColor(0)
  496.  
  497.      ; Create the main window
  498.    cSpringWindow = WIDGET_BASE(TITLE="Spring Example", XOFFSET=10, YOFFSET=10)
  499.  
  500.    topBase = WIDGET_BASE(cSpringWindow, /COLUMN)
  501.  
  502.    drawBase = WIDGET_BASE(topBase, /ROW)
  503.  
  504.    gridBase = WIDGET_BASE(drawBase, /COLUMN)
  505.  
  506.    editDrawLabel = WIDGET_LABEL(gridBase, VALUE='Click to add springs:')
  507.  
  508.    cEditDrawAreaID = WIDGET_DRAW(gridBase, XSIZE=161, YSIZE=161, $
  509.                        /BUTTON_EVENTS, RET=2, UVALUE='MARK_DRAW_AREA')
  510.  
  511.    viewDrawAreaID = WIDGET_DRAW(drawBase, XSIZE=192, YSIZE=192, RET=2)
  512.  
  513.    menuBase = WIDGET_BASE(topBase, /ROW)
  514.  
  515.      ; Create the method drop list
  516.    methodButtonBase = WIDGET_DROPLIST(menuBase, VALUE=cMethodNames, $
  517.                         UVALUE='METHOD_GROUP', TITLE='Rendering Method:')
  518.  
  519.      ; Set the drop list to the current method
  520.    WIDGET_CONTROL, methodButtonBase, SET_DROPLIST_SELECT=cRenderMethod
  521.  
  522.    controlBase = WIDGET_BASE(topBase, /COLUMN)
  523.       
  524.    viewParameterBase = WIDGET_BASE(controlBase, /ROW)
  525.    
  526.    displacementSlider = WIDGET_SLIDER(viewParameterBase, XSIZE=120, $
  527.                           MINIMUM=-100, MAXIMUM=100, $
  528.                           TITLE='Spring Displacement', $
  529.                           VALUE=cSpringDisplacement, UVALUE='HTSLIDER')
  530.    
  531.    cAxSlider = WIDGET_SLIDER(viewParameterBase, XSIZE=120, MINIMUM=-90, $
  532.                  MAXIMUM=90, VALUE=cXAxisRotation, TITLE='X axis rotation', $
  533.                  UVALUE="AX_SLIDER")
  534.    
  535.    cAzSlider = WIDGET_SLIDER(viewParameterBase, XSIZE=120, MINIMUM=0, $
  536.                  MAXIMUM=90, VALUE=cZAxisRotation, TITLE='Z axis rotation', $
  537.                  UVALUE="AZ_SLIDER")
  538.    
  539.    animateParameterBase = WIDGET_BASE(controlBase, /ROW)
  540.  
  541.    strengthSlider = WIDGET_SLIDER(animateParameterBase, XSIZE=120, MINIMUM=1, $
  542.                       MAXIMUM=100, $
  543.                       VALUE=100*cSpringStrength/cMaxSpringStrength, $
  544.                       TITLE='Spring Strength', UVALUE="KSPRING_SLIDER")
  545.    
  546.    numFramesSlider = WIDGET_SLIDER(animateParameterBase, XSIZE=120, $
  547.                        MINIMUM=2, MAXIMUM=40, VALUE=cNumberOfFrames, $'
  548.                        TITLE='Number of frames', UVALUE="NUM_FRAMES_SLIDER")
  549.  
  550.      ; Add base and pushbuttons to Draw and Erase
  551.    PushButtonBase = WIDGET_BASE(animateParameterBase, /COLUMN, XPAD=20)
  552.  
  553.      ; Create "Animate" button
  554.    animateButton_w = WIDGET_BUTTON(PushButtonBase, VALUE='Animate',$
  555.            UVALUE='ANIMATE')
  556.            
  557.      ; Create "Info..." button
  558.    infoButton_w = WIDGET_BUTTON(PushButtonBase, VALUE='Info...', UVALUE='INFO')
  559.  
  560.      ; Display the window and save the previous color table in 
  561.      ; the user value to retore on exit 
  562.    WIDGET_CONTROL, cSpringWindow, /REALIZE, SET_UVALUE=previousState
  563.    
  564.    WIDGET_CONTROL, viewDrawAreaID, GET_VALUE = cViewDrawArea
  565.  
  566.    WIDGET_CONTROL, cEditDrawAreaID, GET_VALUE = cEditDrawArea
  567.    
  568.    DrawGrid               ;Show the editing grid
  569.  
  570.    WSET, cViewDrawArea
  571.  
  572.    maxDisplacement = MAX(cGrid, MIN=minDisplacement)
  573.  
  574.    DrawSurface, 192, DISPLACEMENTGRID=cGrid, VELOCITYGRID=cGrid, $
  575.      MAXDISPLACEMENT=maxDisplacement, MINDISPLACEMENT=minDisplacement, $
  576.      MAXVELOCITY=maxDisplacement, MINVELOCITY=minDisplacement
  577.  
  578.    WSET, swin
  579.  
  580.    XMANAGER, "Spring", cSpringWindow, EVENT_HANDLER = "SpringEvent", $
  581.          GROUP_LEADER = group, CLEANUP="CleanUpSpring", /NO_BLOCK
  582. END
  583.